package frame;

import java.util.Iterator;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import javax.swing.ImageIcon;
import javax.swing.JPanel;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;

import Client.MyClient;
import chartor.Bullet;
import chartor.JUJI;
import chartor.Monster;
import chartor.Plas;
import chartor.Player;
import chartor.SmallBlack;
import chartor.SmallBule;
import chartor.SmallGreen;
import chartor.Smallred;
import chartor.infoNumber;
import opt.Quadtree;

import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;

public class GamePanel extends JPanel {
	private Player playerman;// 记录玩家操作的是那个
	private MyClient myClient;
	private ScheduledThreadPoolExecutor timer = new ScheduledThreadPoolExecutor(1);// 用于线程绘制
	public Quadtree quadtree;// 四叉树
	private Font font1 = new Font("宋体", Font.CENTER_BASELINE, 15);// 人物姓名
	private Font font2 = new Font("宋体", Font.ITALIC, 20);// 枪械姓名
	private Font font3 = new Font("宋体", Font.CENTER_BASELINE, 20);// 枪械子弹数量
	private Font font4 = new Font("宋体", Font.BOLD, 25);// 枪械子弹最大数量
	/**
	 * 背景图
	 */
	private ImageIcon bgImageIcon;
	private int errea = 0;
	/**
	 * 人物走动
	 */
	private ImageIcon[][] walkImages = new ImageIcon[8][4];
	/**
	 * 双缓冲实现
	 */
	private Graphics gBufferGraphics = null;
	private Image iBuffer = null;
	/**
	 * 游戏面板尺寸
	 */
	private int panelWidth;
	private int panelHeight;

	/**
	 * Create the panel.
	 */
	public void paintComponent(Graphics g) {
		super.paintComponent(g);
		if (panelHeight <= 0)
			panelHeight = getHeight();
		if (panelWidth <= 0)
			panelWidth = getWidth();
		if (iBuffer == null && panelHeight > 0 && panelWidth > 0) {
			iBuffer = createImage(panelWidth, panelHeight);
			gBufferGraphics = iBuffer.getGraphics();
		}
		// 开始绘制--绘制在内存画布上
		try {
			paintPanel(gBufferGraphics);
		} catch (Exception e) {
			// TODO: handle exception
			//e.printStackTrace();
		}

		// 内存到画布上
		if (playerman.targetPoint != null) {
			int xm = -playerman.x - playerman.targetPoint.x / 2 + 3 * panelWidth / 4;
			int ym = -playerman.y - playerman.targetPoint.y / 2 + 3 * panelHeight / 4;
			playerman.arrive=false;
			if (xm > 0) {
				xm = 0;
				playerman.arrive=true;
			}
			else if (xm < -(3000 - panelWidth)) {
				xm = -(3000 - panelWidth);
				playerman.arrive=true;
			}
			if (ym > 0) {
				ym = 0;
				playerman.arrive=true;
			}
			else if (ym < -(3000 - panelHeight)) {
				ym = -(3000 - panelHeight);
				playerman.arrive=true;
			}
			g.drawImage(iBuffer, xm, ym, this);
		}
	}

	private void paintPanel(Graphics g) throws Exception {
		/**
		 * 背景图片
		 */
		bgImageIcon.paintIcon(this, g, 0, 0);
		/**
		 * 人物信息ui部分
		 */
		int ui_x=0;
		int ui_y=0;
		if (playerman.targetPoint != null) {
			g.setColor(new Color((float) 1.0, (float) 0.87, (float) 0.675, (float) 1.0));
			 ui_x = playerman.targetPoint.x / 2 + playerman.x - panelWidth * 3 / 4;
			 ui_y = playerman.targetPoint.y / 2 + playerman.y + panelHeight / 4 - 80;
			if (ui_x < 0) {
				ui_x = 0;
			} else if (ui_x > 3000 - panelWidth) {
				ui_x = 3000 - panelWidth;
			}
			if (ui_y < panelHeight - 80) {
				ui_y = panelHeight - 80;
			} else if (ui_y > 2920) {
				ui_y = 2920;
			}

			g.fillRoundRect(ui_x, ui_y, 160, 80, 5, 10);
			g.setColor(new Color((float) 0.82, (float) 0.41, (float) 0.117, (float) 0.9));
			g.drawRoundRect(ui_x, ui_y, 160, 80, 5, 10);
			g.setFont(font2);
			g.setColor(Color.pink);
			g.drawString(playerman.getClasses().getNameString(), ui_x + 5, ui_y + 40);
			g.setFont(font3);
			g.setColor(Color.darkGray);
			g.drawString(playerman.getClasses().getNumber() + "/", ui_x + 80, ui_y + 25);
			g.setFont(font4);
			g.setColor(Color.BLACK);
			g.drawString(playerman.getClasses().getMaxnumber() + "", ui_x + 120, ui_y + 40);
			g.setColor(Color.blue);
			g.drawString("当前关卡:" + myClient.getNum(), ui_x + panelWidth / 2, ui_y + 60);
			
			/**
			 * 小地图
			 */
			g.setColor(Color.DARK_GRAY);
			g.fillRoundRect(ui_x, ui_y+80-panelHeight, 150, 150, 5, 5);
			g.setColor(Color.LIGHT_GRAY);
			g.drawRoundRect(ui_x, ui_y+80-panelHeight, 150, 150, 5, 5);
		}
		/**
		 * 怪物绘制
		 */
		if (Plas.monsters.size() > 0) {
			synchronized (Plas.monsters) {
				Iterator<Monster> iterator = Plas.monsters.iterator();
				while (iterator.hasNext()) {
					try {
						Monster m = iterator.next();
						g.setColor(Color.black);
						g.setFont(font1);
						g.drawString("[" + m.getNameString() + "]", (int) m.getX() - 20, (int) m.getY() - 45);
						if (m.getHealth() > 80)
							g.setColor(Color.GREEN);
						else if (m.getHealth() > 60)
							g.setColor(Color.yellow);
						else if (m.getHealth() > 40)
							g.setColor(Color.ORANGE);
						else if (m.getHealth() > 20)
							g.setColor(Color.RED);
						else
							g.setColor(Color.PINK);
						g.fillRoundRect((int) m.getX() - 30, (int) m.getY() - 40,
								(int) (m.getHealth() / m.HEALTH * 100), 13, 10, 10);
						g.setColor(new Color((float) 0.1, (float) 0.1, (float) 0.5, (float) 0.5));
						g.fillOval((int) m.getX(), (int) m.getY() + 40, 40, 20);
						if (m instanceof Smallred) {// 小红
							g.setColor(Color.RED);
							g.fillRoundRect((int) m.getX(), (int) m.getY(), (int) m.getWidth(), (int) m.getHeight(),
									(int) m.getWidth() / 4, (int) m.getWidth() / 8);
						} else if (m instanceof SmallGreen) {// 小绿
							g.setColor(Color.green);
							g.fillRoundRect((int) m.getX(), (int) m.getY(), (int) m.getWidth(), (int) m.getHeight(),
									(int) m.getWidth() / 4, (int) m.getWidth() / 8);
						} else if (m instanceof SmallBlack) {// 小黑
							g.setColor(Color.black);
							g.fillRoundRect((int) m.getX(), (int) m.getY(), (int) m.getWidth(), (int) m.getHeight(),
									(int) m.getWidth(), (int) m.getWidth());
						} else if (m instanceof SmallBule) {// 小蓝
							g.setColor(Color.blue);
							g.fillRoundRect((int) m.getX(), (int) m.getY(), (int) m.getWidth(), (int) m.getHeight(),
									(int) m.getWidth() / 2, (int) m.getWidth() / 2);
							if (m.getuGun().jindutiao != null)
								g.fillRect((int) m.getX() - 30, (int) m.getY() - 80,
										(int) (m.getuGun().jindutiao.getJindu() / m.getuGun().jindutiao.getMaxjindu()
												* 100),
										5);
						}
						g.setColor(Color.GRAY);
						g.drawRoundRect((int) m.getX(), (int) m.getY(), (int) m.getWidth(), (int) m.getHeight(),
								(int) m.getWidth() / 4, (int) m.getWidth() / 8);
						//绘制在小地图上
						g.setColor(Color.red);
						g.drawOval(ui_x+(int)(m.getX()*0.05), ui_y+(int)(m.getY()*0.05)+80-panelHeight, (int)(m.getWidth()/10), (int)(m.getWidth()/10));
					} catch (Exception e) {
						// TODO: handle exception
						e.printStackTrace();
						break;
					}
				}
			}
		}
		// 玩家信息绘制
		for (Player s : Plas.players.values()) {
			/**
			 * 人物姓名
			 */
			// 优化只画自己一个人
			g.setColor(Color.black);
			g.setFont(font1);
			g.drawString("[" + s.getClasses().getNameString() + "]" + s.getNameString(), (int) s.getX() - 20,
					(int) s.getY() - 45);
			g.setColor(Color.red);
			g.setFont(font1);
			g.drawString("<" + s.getGotnumer() + ">", (int) s.getX() + 5, (int) s.getY() - 80);
			if (s.getHealth() > 80)
				g.setColor(Color.GREEN);
			else if (s.getHealth() > 60)
				g.setColor(Color.yellow);
			else if (s.getHealth() > 40)
				g.setColor(Color.ORANGE);
			else if (s.getHealth() > 20)
				g.setColor(Color.RED);
			else
				g.setColor(Color.PINK);
			g.fillRoundRect((int) s.getX() - 30, (int) s.getY() - 80, (int) (s.getHealth() / s.HEALTH * 100), 13, 10,
					10);
			g.setColor(new Color((float) 0.1, (float) 0.1, (float) 0.5, (float) 0.5));
			g.fillOval((int) s.getX(), (int) s.getY() + 40, 40, 20);

//			//身体
//			g.setColor(Color.black);
//			g.fillRoundRect((int) s.getX(), (int) s.getY() -10, 40, 50, 10, 20);
//			//头部
//			g.setColor(Color.yellow);
//			g.fillRoundRect((int) s.getX(), (int) s.getY() - 40, 40, 40, 40, 40);
//			//眼睛
//			g.setColor(Color.lightGray);
//			g.fillRect((int) s.getX()+15, (int) s.getY() - 25, 5, 2);
//			g.fillRect((int) s.getX()+25, (int) s.getY() - 25, 5, 2);
			if (s.getHealth() > 0)
				walkImages[s.getDirection() - 1][errea].paintIcon(this, g, (int) s.getX(), (int) s.getY() - 40);
			else {
				g.setColor(Color.red);
				g.fillOval((int) s.getX(), (int) s.getY(), 100, 30);
			}
			g.setColor(Color.ORANGE);
			if (s.getClasses().jindutiao != null)
				g.fillRect((int) s.getX() - 30, (int) s.getY() - 80,
						(int) (s.getClasses().jindutiao.getJindu() / s.getClasses().jindutiao.getMaxjindu() * 100), 5);
			//绘制在小地图上
			if(s.equals(playerman))
			g.setColor(Color.green);
			else {
				g.setColor(Color.yellow);
			}
			g.drawOval(ui_x+(int)(s.getX()*0.05), ui_y+(int)(s.getY()*0.05)+80-panelHeight, (int)(s.getWidth()/10), (int)(s.getWidth()/10));
		}
		/**
		 * 子弹绘制
		 */
		g.setColor(Color.black);
		Iterator<Bullet> iterable = Plas.bullets.iterator();
		while (iterable.hasNext()) {
			try {
				// 这里也可以加一个优化
				Bullet b = iterable.next();
				g.fillRoundRect(b.x, b.y, (int) b.getWidth(), (int) b.getHeight(), (int) b.getWidth(),
						(int) b.getHeight());
			} catch (Exception e) {
				//e.printStackTrace();
				break;
			}
		}
		
		/**
		 * 瞄准线和准心部分
		 */
		g.setColor(new Color((float) 1.0, (float) 0.0, (float) 0.3, (float) 0.85));
		if (playerman.targetPoint != null) {
			if (playerman.getClasses() instanceof JUJI) {
				if(!playerman.arrive) {
				g.drawLine((int) playerman.getX(), (int) playerman.getY(),
						(int) playerman.targetPoint.x + playerman.x - panelWidth / 2,
						(int) playerman.targetPoint.y + playerman.y - panelHeight / 2);
				}else {
					g.drawLine((int) playerman.getX(), (int) playerman.getY(),
							(playerman.targetpoint_x+playerman.x)/2,
							(playerman.targetpoint_y+playerman.y)/2);
				}
			}
			Graphics2D graphics2d = (Graphics2D) g;
			graphics2d.setStroke(new BasicStroke(3.0f));
			graphics2d.setColor(new Color((float) 0.0, (float) 0.0, (float) 1.0, (float) 1.0));
			if(!playerman.arrive) {
			int line_x = (int) playerman.targetPoint.x * 3 / 2 + playerman.x - panelWidth * 3 / 4;
			int line_y = (int) playerman.targetPoint.y * 3 / 2 + playerman.y - panelHeight * 3 / 4;
			graphics2d.drawLine(line_x - 15, line_y, line_x + 15, line_y);
			graphics2d.drawLine(line_x, line_y - 15, line_x, line_y + 15);
			playerman.targetpoint_x=line_x;
			playerman.targetpoint_y=line_y;
			}else {
				int line_x = (int) playerman.targetPoint.x+ui_x;
				int line_y = (int) playerman.targetPoint.y+ui_y+80-panelHeight;
				graphics2d.drawLine(line_x - 15, line_y, line_x + 15, line_y);
				graphics2d.drawLine(line_x, line_y - 15, line_x, line_y + 15);
				playerman.targetpoint_x=line_x;
				playerman.targetpoint_y=line_y;
			}
			graphics2d.setStroke(new BasicStroke(1.0f));
		}
		
		/**
		 * 伤害数字显示
		 */
		g.setColor(Color.red);
		g.setFont(new Font("宋体", Font.CENTER_BASELINE, 20));
		Iterator<infoNumber> iterator = Plas.infoNumbers.iterator();
		while (iterator.hasNext()) {
			infoNumber infoNumber = iterator.next();
			g.drawString(infoNumber.getContentString(), infoNumber.x, infoNumber.y);
			infoNumber.time--;
			if (infoNumber.time == 0)
				iterator.remove();
		}
	}
	public GamePanel(MyClient myClient) {
		addMouseMotionListener(new MouseMotionAdapter() {
			@Override
			public void mouseDragged(MouseEvent e) {
				playerman.targetPoint = e.getPoint();
			}

			@Override
			public void mouseMoved(MouseEvent e) {
				playerman.targetPoint = e.getPoint();
			}
		});
		addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				if (e.getButton() == 1) {
					playerman.setJ(true);
				}
			}

			@Override
			public void mouseReleased(MouseEvent e) {
				if (e.getButton() == 1) {
					playerman.setJ(false);
				}
			}
		});
		addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				if (playerman != null)
					switch (e.getKeyCode()) {
					case 65:
						playerman.setA(true);
						break;
					case 83:
						playerman.setS(true);
						break;
					case 68:
						playerman.setD(true);
						break;
					case 87:
						playerman.setW(true);
						break;
					case 16:
						playerman.setShift(true);
						break;
					case 74:
						playerman.setJ(true);
						break;
					case 82:
						playerman.setR(true);
						break;
					case 49:
						playerman.setNum1(true);
						break;
					case 50:
						playerman.setNum2(true);
						break;
					case 51:
						playerman.setNum3(true);
						break;
					default:
						break;
					}
			}
			@Override
			public void keyReleased(KeyEvent e) {
				if (playerman != null)
					switch (e.getKeyCode()) {
					case 65:
						playerman.setA(false);
						break;
					case 83:
						playerman.setS(false);
						break;
					case 68:
						playerman.setD(false);
						break;
					case 87:
						playerman.setW(false);
						break;
					case 16:
						playerman.setShift(false);
						break;
					case 74:
						playerman.setJ(false);
						break;
					case 82:
						playerman.setR(false);
						break;
					case 49:
						playerman.setNum1(false);
						break;
					case 50:
						playerman.setNum2(false);
						break;
					case 51:
						playerman.setNum3(false);
						break;
					default:
						break;
					}
			}
		});
		this.myClient = myClient;
		// 添加组件监听器
		addComponentListener(new ComponentAdapter() {
			@Override
			public void componentResized(ComponentEvent e) {
				panelHeight = getHeight();
				panelWidth = getWidth();
				if (panelWidth > 0 && panelHeight > 0) {
					// 创建双缓冲资源
					iBuffer = createImage(3000, 3000);
					gBufferGraphics = iBuffer.getGraphics();
				}
			}
		});
		loadres();
		repainTimer.start();
		qiehuang();
		quadtree = new Quadtree(0, new Rectangle(3000, 3000));
		// 建立成功后发送ok信息
		hideCursor();
		myClient.putOK();
	}

	public void loadres() {
		bgImageIcon = new ImageIcon("res/bg.jpg");
		for (int i = 1; i <= 8; i++) {
			for (int j = 1; j <= 4; j++) {
				walkImages[i - 1][j - 1] = new ImageIcon("res/" + i + "." + j + ".png");
			}
		}
	}

	public Player getPlayerman() {
		return playerman;
	}

	public void setPlayerman(Player playerman) {
		this.playerman = playerman;
	}

	public void hideCursor() {
		Image image = Toolkit.getDefaultToolkit().createImage(new MemoryImageSource(0, 0, new int[0], 0, 0));
		this.setCursor(Toolkit.getDefaultToolkit().createCustomCursor(image, new Point(0, 0), null));
	}

	private void qiehuang() {
		timer.scheduleAtFixedRate(new Runnable() {

			@Override
			public void run() {
				errea = (errea + 1) % 4;
			}
		}, 0, 150, TimeUnit.MILLISECONDS);
	}

	private javax.swing.Timer repainTimer = new javax.swing.Timer(16, new ActionListener() {
		@Override
		public void actionPerformed(ActionEvent e) {
			try {
				repaint();
			} catch (Exception e21) {
				// TODO: handle exception
				e21.printStackTrace();
			}
		}
	});
}
